import java.util.ArrayList;
import java.util.List;

class Director {
    List<Element> elements = new ArrayList<Element>();

    public void add(Element element) {
        elements.add(element);
    }

    public void remove(Element element) {
        elements.remove(element);
    }

    public void show(Visitor visitor) {
        for (Element element : elements) {
            element.show(visitor);
        }
    }
}

abstract class Element {
    public abstract void show(Visitor visitor);
}

class ElementA extends Element {
    @Override
    public void show(Visitor visitor) {
        visitor.showElementA(this);
    }
}

class ElementB extends Element {
    @Override
    public void show(Visitor visitor) {
        visitor.showElementB(this);
    }
}

public abstract class Visitor {

    public static void main(String[] args) {
        Director d = new Director();
        d.add(new ElementA());
        d.add(new ElementB());
        d.show(new Visitor1());
        d.show(new Visitor2());
    }

    public abstract void showElementA(ElementA elementA);

    public abstract void showElementB(ElementB elementB);
}

class Visitor1 extends Visitor {
    @Override
    public void showElementA(ElementA elementA) {
        System.out.println((this.getClass().getName() + " visit " + elementA.getClass().getName()));
    }

    @Override
    public void showElementB(ElementB elementB) {
        System.out.println((this.getClass().getName() + " visit " + elementB.getClass().getName()));
    }
}

class Visitor2 extends Visitor {
    @Override
    public void showElementA(ElementA elementA) {
        System.out.println((this.getClass().getName() + " visit " + elementA.getClass().getName()));
    }

    @Override
    public void showElementB(ElementB elementB) {
        System.out.println((this.getClass().getName() + " visit " + elementB.getClass().getName()));
    }
}